package com.voxel.sense.infomsg.base;

import android.os.Handler;
import android.support.annotation.IntDef;
import android.support.v7.util.DiffUtil;

import com.example.com.common.app.BaseContract;
import com.example.com.common.app.BaseRecyclerPresenter;
import com.example.com.common.utils.NetworkUtils;
import com.example.com.common.utils.ToastUtil;
import com.example.com.common.widget.diffui.DiffUiDataCallBack;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;

import cyy.example.com.facotry.Factory;

/**
 * Created by ChenYiYao on 2018/2/8.
 */

public abstract class RecyclerViewPresenter<View extends BaseContract.RecyclerView>
        extends BaseRecyclerPresenter<View> {

    protected boolean noMore;// 没有更多数据
    protected boolean refreshIng;// 正在刷新
    protected boolean loadMoreIng;// 正在加载更多 筛选

    private long refreshTime; //刷新时间
    private final int REFRESH_MIN_INTERVAL = 1500;//最小刷新间隔，避免不必要的频繁刷新

    private int mPageDataSize = 10;//每次加载数据的个性
    private int PAGE_NUMB = 1; //数据的页数,页数从1开始
    public int mRefreshWay = RecyclerViewPresenter.WayConstants.NORMAL;//刷新方式
    private Handler mHandler;


    public int getPageDataSize() {
        return mPageDataSize;
    }

    public void setPageDataSize(int pageDataSize) {
        mPageDataSize = pageDataSize;
    }

    public RecyclerViewPresenter(View view) {
        super(view);
        mHandler = new Handler();
    }

    /**
     * 刷新获取数据
     */
    protected void startRefreshData() {
        if (mView == null)
            return;

        //刷新时间间隔过小，或者正在刷新或加载更多时，不再进行刷新
        if (Math.abs(System.currentTimeMillis() - refreshTime) < REFRESH_MIN_INTERVAL || refreshIng || loadMoreIng) {
            if (refreshIng || loadMoreIng) {
                ToastUtil.showToastLong(Factory.app(), "正在加载数据，请稍后再刷新");
            } else {
                ToastUtil.showToastLong(Factory.app(), "操作过于频繁，请稍后再试");
                mView.onRefreshFinish();
            }
            return;
        }
        //改变标记
        refreshIng = true;
        loadMoreIng = false;
        noMore = false;
        refreshTime = System.currentTimeMillis();
        //恢复页数
        PAGE_NUMB = 1;
        mView.onShowNoMore(noMore);
        //获取数据
        loadData();
    }


    /**
     * 开始加载更多
     */
    protected void startLoadMoreData() {
        if (mView == null)
            return;
        //正在刷新或者正在加载更多则不进行拉取数据
        if (!(refreshIng || loadMoreIng)) {
            if (NetworkUtils.isConnected()) {
                int itemCount = mView.getRecyclerViewAdapter().getItemCount();
                if (noMore || itemCount < mPageDataSize) {
                    //已没有更多的数据
                    ToastUtil.showToastLong(Factory.app(), "已到底部，暂无更多数据");
                    mView.onLoadMoreFinish();
                    mView.onShowNoMore(noMore);
                    return;
                }
                //拉取更多数据
                loadMoreIng = true;
                //加载更多数据
                loadMoreData();
            }
        } else {
            ToastUtil.showToastLong(Factory.app(), "正在加载数据，请稍后再刷新");
            mView.onLoadMoreFinish();
        }
    }

    /**
     * 具体的进行加载数据的方法
     */
    protected abstract void loadData();


    /**
     * 具体加载更多数据的方法
     */
    protected abstract void loadMoreData();

    /**
     * 刷新数据加载完成
     *
     * @param list 新的数据集
     */
    protected void loadDataComplete(List list) {
        loadDataComplete(list, null);
    }

    protected void loadDataComplete(List list, DiffUiDataCallBack callback) {
        if (mView == null)
            return;
        if (list != null && list.size() > 0) {
            if (list.size() < mPageDataSize) {//回来的数据少于指定数据则没有更多数据了
                noMore = true;
                mView.onShowNoMore(noMore);
            }
            if (refreshIng) {
                //下拉刷新
                refreshData(list, callback);
                PAGE_NUMB++;
            } else if (loadMoreIng) {
                //加载更多
                List items = mView.getRecyclerViewAdapter().getItems();
                list.addAll(0, items);
                refreshData(list, callback);
                PAGE_NUMB++;
            }

        } else {
            if (refreshIng) {
                mView.getRecyclerViewAdapter().clear();
            } else if (loadMoreIng) {
                noMore = true;
                mView.onShowNoMore(noMore);
            }
            mView.onAdapterDataChanged();
            loadFinish();
        }
    }


    /**
     * 数据加载失败
     */
    protected void LoadDataFailure() {
        loadFinish();
    }

    /**
     * 加载结束后调用
     * 收起恢复刷新加载标记
     */
    private void loadFinish() {
        if (mView == null)
            return;
        //数据刷新完成，还原状态
        if (refreshIng) {
            mView.onRefreshFinish();
        } else if (loadMoreIng) {
            mView.onLoadMoreFinish();
        }
        refreshIng = false;
        loadMoreIng = false;
    }


    /**
     * 刷新数据
     */
    private void refreshData(final List list, final DiffUiDataCallBack callback) {
        if (mRefreshWay == RecyclerViewPresenter.WayConstants.NORMAL) {
            //普通刷新
            RefreshData(list);
            loadFinish();
        } else if (mRefreshWay == RecyclerViewPresenter.WayConstants.DIFF) {
            if (callback != null) {
                mHandler.removeCallbacksAndMessages(null);//由于有异步操作，发送前先释放之前的消息
                final List items = mView.getRecyclerViewAdapter().getItems();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        calculateListData(items, list, callback);
                    }
                }).start();
            } else {
                RefreshData(list);
                loadFinish();
            }
        }
    }

    /**
     * 使用diif工具进行计算操作
     */
    private void calculateListData(List oldList, final List newList, DiffUiDataCallBack callback) {
        callback.setData(oldList, newList);
        final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback);
        //回到主线程更新
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                DiffRefreshData(diffResult, newList);
                loadFinish();

            }
        });

    }


    /**
     * 设置刷新方式
     *
     * @param refreshWay
     */
    public void setRefreshWay(@RecyclerViewPresenter.WayConstants.Unit int refreshWay) {
        mRefreshWay = refreshWay;
    }


    public interface WayConstants {
        int NORMAL = 1; //普通方式
        int DIFF = 2; //DiffUtils刷新

        @IntDef({NORMAL, DIFF})
        @Retention(RetentionPolicy.SOURCE)
        public @interface Unit {
        }
    }


    public int getPAGE_NUMB() {
        return PAGE_NUMB;
    }

    public void setPAGE_NUMB(int PAGE_NUMB) {
        this.PAGE_NUMB = PAGE_NUMB;
    }
}
